package xyz.twj.utils.file;

import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * @author : TianWenjian
 */
public class ZipUtils {

    /**
     * 创建压缩文件
     *
     * @param targetPath 目标
     * @param sourcePath 源
     */
    public static void zip(String targetPath, String sourcePath) throws IOException {
        File sourceFile = new File(sourcePath);
        File targetFile = new File(targetPath);

        zip(targetFile, sourceFile);
    }

    /**
     *
     * @param targetFile
     * @param sourceFile
     * @throws IOException
     */
    public static void zip(File targetFile, File sourceFile) throws IOException {
        //创建zip输出流
        if (!targetFile.exists()) {
            targetFile.createNewFile();
        }
        try (ZipOutputStream out = new ZipOutputStream(new FileOutputStream(targetFile));
             BufferedOutputStream bos = new BufferedOutputStream(out, 1024 * 10)) {
            //调用函数
            compress(out, bos, sourceFile, sourceFile.getName());
        }
    }

    /**
     * @param out    zip 描述
     * @param bos    zip 增加了一个缓冲流， 用out直接输出也可以其实，使用了缓冲流要记得flush
     *               缓冲流可以不必每个字节都写磁盘
     * @param source 源文件
     * @throws IOException
     */
    private static void compress(ZipOutputStream out, BufferedOutputStream bos, File source, String currPath) throws IOException {
        if (source.isFile()) {
            out.putNextEntry(new ZipEntry(currPath));
            FileInputStream fos = new FileInputStream(source);
            BufferedInputStream bis = new BufferedInputStream(fos);

            int tag;
            //将源文件写入到zip文件中
            while ((tag = bis.read()) != -1) {
                bos.write(tag);
            }
            bos.flush();
            bis.close();
            fos.close();
        } else {
            //取出文件夹中的文件（或子文件夹）
            File[] flist = source.listFiles();
            //如果文件夹为空，则只需在目的地zip文件中写入一个目录进入点
            if (flist.length == 0) {
                out.putNextEntry(new ZipEntry(currPath + "/"));
            } else { //如果文件夹不为空，则递归调用compress，文件夹中的每一个文件（或文件夹）进行压缩
                for (int i = 0; i < flist.length; i++) {
                    compress(out, bos, flist[i], currPath + "/" + flist[i].getName());
                }
            }
        }

    }

    public static void main(String[] args) {
        try {
            zip("C:\\Users\\田文健\\Desktop\\export.zip", "C:\\Users\\田文健\\Desktop\\export");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
